package com.tb.client.interceptor;

import com.tb.client.support.sso.MySSOClientManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@Component
public class MySSOClientInterceptor implements HandlerInterceptor {

    @Autowired
    MySSOClientManager mySSOClientManager;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession httpSession = request.getSession();
        /**
         * session中isLogin为true，表示用户已登录，无需走认证中心的认证流程
         */
        Boolean isLogin = (Boolean) httpSession.getAttribute("isLoginFlag");
        if(Boolean.TRUE.equals(isLogin)){
            return true;
        }

        String token = request.getParameter("token");
        /**
         * 判断请求URL中是否带了参数token，带了token说明是认证中心过来的请求，否则是应用过来的请求
         */
        if(StringUtils.isEmpty(token)){
            /**
             *如果token为空，到这里说明session中的isLogin也不是true，说明用户未通过认证中心的认证，需要进行认证
             * 注意：这个地方不能直接跳转到认证中心的登录页面，而是应用由认证中心决定是否跳转到登录页面
             * 原因：因为A系统登录成功后，新建一个页签输入B系统地址，这个时候token是null，如果直接跳转到认证中心的
             * 登录页面就又要重新登录了，显然不对，这样应该先让认证中心检测session中是否存在token这个属性并且有值，如果
             * 有值，则说明已经有系统登录过了，不需要重新登录，直接重定向到B系统的地址即可；如果没有值，这说明可能认证中心
             * 删除了之前系统登录设置的token，session超时之类的，这个时候就需要重新登录并且验证
             */
            mySSOClientManager.loginCheck(request,response);
            return false;
        }else {
            /**
             * 如果token不为空，说明用户通过了认证中心的认证；
             * 通过认证的用户，需要拿token到认证中心进行校验，获取用户的信息；
             * 注意：这个地方不能用response.sendRedirect方式进行跳转，首先，这是应该是同步的，需要等待认证中心的响应才能继续向下走；
             * 其次，认证中心不能再进行重定向，只能返回json数据这里。
             */
            String credificate = mySSOClientManager.verifyToken(token);
            if(StringUtils.isEmpty(credificate)){
                /**
                 * 如果用户信息为空，说明认证中心已经清除了该用户的会话，需要重新登录
                 */
                mySSOClientManager.toSSOLogin(request,response);
                return false;
            }else {
                /**
                 * 如果用户信息不为空，说明用户会话正常，并设置用户未已登录，后期就无需进行认证了
                 */
                httpSession.setAttribute("isLoginFlag",true);
                request.setAttribute("account",credificate);
                return true;
            }
        }
    }
}
